package com.bicon.botu.file.upload.service;

import com.bicon.botu.core.base.common.Constants;
import com.bicon.botu.core.base.common.entity.BaseResult;
import com.bicon.botu.core.base.common.utils.JsonUtil;
import com.bicon.botu.core.base.common.utils.UUIDUtil;
import com.bicon.botu.file.upload.common.*;
import com.bicon.botu.file.upload.vo.AudioProcess;
import com.bicon.botu.file.upload.vo.VideoProcess;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.MultiValueMap;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import com.bicon.botu.file.upload.vo.FileInfo;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 文件上传服务
 *
 * @author tandk
 * @date 2017/3/1 0001
 */
@Slf4j
@Service
public class FileUploadService {

    @Value("${file.disk.path}")
    String diskPath;

    @Value("${file.server.path}")
    String serverPath;

    /**
     * 上传文件服务
     *
     * @param request request
     * @param appName 调用的服务id
     * @param module  调用的服务名
     * @param width   压缩宽度
     * @param height  压缩高度
     * @return 文件信息
     * @throws IOException
     */
    public List<FileInfo> doUpload(HttpServletRequest request, String appId, String appName, String module,
                                   String business, String entityId, Integer width, Integer height, String typeAppicon) throws IOException {
        List<FileInfo> fileList = new ArrayList<>();
        //创建一个通用的多部分解析器
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        String dayData = sdf.format(new Date());
        CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());
        if (multipartResolver.isMultipart(request)) {
            //转换成多部分request
            MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
            //取得request中的所有文件名
            Iterator<String> iter = multiRequest.getFileNames();
            int number = 0;
            while (iter.hasNext()) {
                //记录上传过程起始时的时间，用来计算上传时间
                long pre = System.currentTimeMillis();
                //取得上传文件
                MultipartFile file = multiRequest.getFile(iter.next());
                if (file != null) {
                    //取得当前上传文件的文件名称
                    String myFileName = file.getOriginalFilename();
                    //如果名称不为“”,说明该文件存在，否则说明该文件不存在
                    if (myFileName.trim() != "") {
                        FileInfo fileInfo = new FileInfo();
                        //设置文件名
                        String type = "";
                        String realName = "";
                        if (StringUtils.isNotBlank(typeAppicon)) {
                            if (myFileName.lastIndexOf(".") != -1) {
                                type = myFileName.substring(myFileName.lastIndexOf("."));
                            }
                            realName = typeAppicon;
                        } else if (StringUtils.isAnyBlank(entityId)) {
                            if (myFileName.lastIndexOf(".") != -1) {
                                type = myFileName.substring(myFileName.lastIndexOf("."));
                            }
                            realName = UUIDUtil.get();
                        } else {
                            type = ".jpg";
                            realName = entityId;
                        }
                        //定义上传路径,检查文件目录是否存在如果不存在则创建
                        BufferedImage image = ImageIO.read(file.getInputStream());
                        String normalPathFolder = "";
                        String smallPathFolder = "";
                        String normalPath = "";
                        String smallPath = "";
                        VideoProcess videoProcess = new VideoProcess();
                        AudioProcess audioProcess = new AudioProcess();
                        if (image != null) {
                            //图片上传
                            //如果是照片并且不是app图标的图，进行压缩处理
                            if (StringUtils.isAnyBlank(typeAppicon)) {
                                normalPathFolder = appName + "/" + module + "/" + business + "/n/" + dayData + "/";
                                smallPathFolder = appName + "/" + module + "/" + business + "/s/" + dayData + "/";
                                normalPath = normalPathFolder + realName + type;
                                smallPath = smallPathFolder + realName + type;
                            } else {
                                normalPath = appName + "/" + typeAppicon + "/" + typeAppicon + "/" + realName + type;
                            }
                            FileUtils.createFolder(new File(diskPath + "/" + normalPathFolder));
                            file.transferTo(new File(diskPath + "/" + normalPath));
                            if (StringUtils.isAnyBlank(typeAppicon)) {
                                FileUtils.createFolder(new File(diskPath + "/" + smallPathFolder));
                                Map<String, Integer> picParam = ImageUtil.scale(diskPath + "/" + normalPath, diskPath + "/" + smallPath, width, height);
                                fileInfo.setW(picParam.get("w"));
                                fileInfo.setH(picParam.get("h"));
                                fileInfo.setWidth(picParam.get("width"));
                                fileInfo.setHeight(picParam.get("height"));
                                fileInfo.setZoomPath(serverPath + smallPath);
                                fileInfo.setRemark("图片缩放");
                            }
                            fileInfo.setPath(serverPath + normalPath);
                        } else if (!".apk".equals(type) && !VideoFileUtil.isVedioFile(myFileName) && !AudioFileUtil.isAudioFile(myFileName)) {
                            //文件上传
                            FileUtils.createFolder(new File(diskPath + "/" + appName + "/file/" + dayData + "/"));
                            normalPath = appName + "/file/" + dayData + "/" + realName + type;
                            file.transferTo(new File(diskPath + "/" + normalPath));
                            fileInfo.setPath(serverPath + normalPath);
                        } else if (VideoFileUtil.isVedioFile(myFileName)) {
                            //视频上传
                            String normalVideoPath = "";
                            String normalCutPath = "";
                            if (null != realName) {
                                normalVideoPath = appName + "/" + module + "/" + business + "/" + dayData;
                                normalCutPath = appName + "/" + module + "/" + business + "/" + dayData;
                            }
                            String videoType = myFileName.substring(myFileName.lastIndexOf("."));
                            FileUtils.createFolder(new File(diskPath + "/" + normalVideoPath));
                            FileUtils.createFolder(new File(diskPath + "/" + normalCutPath));
                            File s = new File(diskPath + "/" + normalVideoPath + "/" + realName + videoType);
                            file.transferTo(s);
                            CoverVideo coverVideo = new CoverVideo(diskPath + "/" + normalVideoPath + "/" + realName + videoType);
                            BaseResult<VideoProcess> baseResult = coverVideo.beginCover(s, diskPath + "/" + normalVideoPath + "/" + realName, diskPath + "/" + normalCutPath + "/", realName, videoType);
                            if (baseResult.getCode() == Constants.RESPONSE_CODE_200) {
                                videoProcess = baseResult.getData();
                            }
                            if (null != videoProcess) {
                                if (StringUtils.isNotEmpty(videoProcess.getVideoCoverPath())) {
                                    fileInfo.setPath(serverPath.substring(0, serverPath.length() - 1) + videoProcess.getVideoCoverPath().substring(diskPath.length()));
                                }
                                if (StringUtils.isNotEmpty(videoProcess.getVideoCutPicturePath())) {
                                    fileInfo.setVideoCapturePath(serverPath.substring(0, serverPath.length() - 1) + videoProcess.getVideoCutPicturePath().substring(diskPath.length()));
                                }
                                if (StringUtils.isNotEmpty(videoProcess.getVideoTime())) {
                                    fileInfo.setDuration(videoProcess.getVideoTime());
                                }
                            }
                        } else if (AudioFileUtil.isAudioFile(myFileName)){
                            //上传音频格式
                            String normalAudioPath = "";
                            if (null != realName) {
                                normalAudioPath = appName + "/" + module + "/" + business + "/" + dayData;
                            }
                            String audioType = myFileName.substring(myFileName.lastIndexOf("."));
                            FileUtils.createFolder(new File(diskPath + "/" + normalAudioPath));
                            File s = new File(diskPath + "/" + normalAudioPath + "/" + realName + audioType);
                            file.transferTo(s);
                            CoverAudio coverVideo = new CoverAudio(diskPath + "/" + normalAudioPath + "/" + realName + audioType);
                            BaseResult<AudioProcess> baseResult = coverVideo.beginCover(s, diskPath + "/" + normalAudioPath + "/" + realName);
                            if (baseResult.getCode() == Constants.RESPONSE_CODE_200){
                                audioProcess = baseResult.getData();
                            }
                            if (null != audioProcess) {
                                if (StringUtils.isNotEmpty(audioProcess.getAudioCoverPath())) {
                                    fileInfo.setPath(serverPath.substring(0, serverPath.length() - 1) + audioProcess.getAudioCoverPath().substring(diskPath.length()));
                                }
                                if (StringUtils.isNotEmpty(audioProcess.getAudioTime())) {
                                    fileInfo.setDuration(audioProcess.getAudioTime());
                                }
                            }
                        }else {
                            //其他文件上传
                            FileUtils.createFolder(new File(diskPath + "/" + appName + "/file/apk/" + dayData + "/"));
                            normalPath = appName + "/file/apk/" + dayData + "/" + file.getOriginalFilename();
                            file.transferTo(new File(diskPath + "/" + normalPath));
                            fileInfo.setPath(serverPath + normalPath);
                        }
                        //rpc保存记录
                        MultiValueMap<String, MultipartFile> multiFileMap = ((MultipartHttpServletRequest) request).getMultiFileMap();
                        Set<String> set = new TreeSet<String>();
                        set = multiFileMap.keySet();
                        List<String> list = new ArrayList();
                        list.addAll(set);
                        fileInfo.setRequestName(list.get(number));
                        fileInfo.setAppId(appId);
                        fileInfo.setAppName(appName);
                        fileInfo.setModule(module);
                        fileInfo.setBusiness(business);
                        fileInfo.setEntityId(entityId);
                        fileInfo.setRealName(file.getOriginalFilename());
                        fileInfo.setFileExt(type);
                        if (VideoFileUtil.isVedioFile(myFileName)) {
                            if (StringUtils.isNotEmpty(videoProcess.getVideoSize())) {
                                String a = "KB";
                                if (StringUtils.contains(videoProcess.getVideoSize(),"KB") || StringUtils.contains(videoProcess.getVideoSize(),"kb")){
                                    String c = Double.parseDouble(StringUtils.substring(videoProcess.getVideoSize(),0,videoProcess.getVideoSize().length()-3))+"MB";
                                    fileInfo.setFileSize(c);
                                }else {
                                    fileInfo.setFileSize(videoProcess.getVideoSize());
                                }
                            } else {
                                if (StringUtils.contains(videoProcess.getVideoSize(),"KB") || StringUtils.contains(videoProcess.getVideoSize(),"kb")){
                                    String c = Double.parseDouble(StringUtils.substring(videoProcess.getVideoSize(),0,videoProcess.getVideoSize().length()-3))+"MB";
                                    fileInfo.setFileSize(c);
                                }else {
                                    fileInfo.setFileSize(FileUtils.convertFileSize(file.getSize()));
                                }
                            }
                        } else if (AudioFileUtil.isAudioFile(myFileName)) {
                            if (StringUtils.isNotEmpty(audioProcess.getAudioSize())) {
                                fileInfo.setFileSize(audioProcess.getAudioSize());
                            } else {
                                fileInfo.setFileSize(FileUtils.convertFileSize(file.getSize()));
                            }
                        } else {
                            fileInfo.setFileSize(FileUtils.convertFileSize(file.getSize()));
                        }
                        fileInfo.setRealSize(file.getSize());
                        //记录上传该文件后的时间
                        long finaltime = System.currentTimeMillis();
                        //记录上传文件消耗时间
                        fileInfo.setUploadTime(finaltime - pre);
                        fileList.add(fileInfo);
                        log.info("上传文件成功：【{}】", JsonUtil.toJson(fileInfo));
                    }
                }
            }
        }
        return fileList;
    }

    /**
     * 删除文件
     *
     * @param filePath 文件路径
     * @return
     */
    public boolean deleteFile(String filePath) {
        boolean bN = FileUtils.deleteFile(diskPath + "/" + filePath);
        if (bN) {
            String filePathS = filePath.replace("/n/", "/s/");
            FileUtils.deleteFile(diskPath + "/" + filePathS);
        } else {
            return bN;
        }
        return bN;
    }

    /**
     * 删除文件
     *
     * @param type     文件类型：0：图片，1：视频，2：语音
     * @param filePath 文件路径
     * @return
     */
    public boolean deleteFileOperation(String type, String filePath) {
        boolean result = false;
        String[] fileList = filePath.split(",");
        URL url;
        for (int i = 0; i < fileList.length; i++) {
            try {
                url = new URL(fileList[i]);
                String fileUrlPath = url.getPath();
                result = FileUtils.deleteFile(diskPath + fileUrlPath);
                if (result) {
                    String filePathS = "";
                    if (FileUploadConstants.FILE_TYPE_PICTURE.equals(type)) {
                        filePathS = fileUrlPath.replace("/n/", "/s/");
                    } else if (FileUploadConstants.FILE_TYPE_VIDEO.equals(type)) {
                        filePathS = fileUrlPath.replace(".mp4", ".jpg");
                    }
                    FileUtils.deleteFile(diskPath + filePathS);
                }
            } catch (Exception e) {
                log.error("url转换失败");
                return false;
            }
        }
        return result;
    }
}
